/**
 * @fileoverview 项目骨架生成模块
 * 负责根据用户配置生成项目的基础文件结构和配置文件
 */

import {
  sources,
  jsSources,
  tsSources,
  jsTsconfigStrictSources,
  tsTsconfigStrictSources,
  js_dao3config_npmPackage_client,
  js_dao3config_npmPackage_server,
  ts_dao3config_npmPackage_client,
  ts_dao3config_npmPackage_server,
  ts_dao3config,
  js_dao3config,
  ts_i18nSources,
  js_i18nSources,
  i18nSources,
} from "./assets/sources.js";
import { copyFile, createDir } from "./util.js";
import { parse, resolve, relative } from "path";
import { default as chalk } from "chalk";

/**
 * 创建项目骨架
 * @param {string} basepath - 项目根目录路径
 * @param {Object} answers - 用户配置选项
 * @throws {Error} 当创建过程中出现错误时抛出异常
 */
async function skeleton(basepath, answers) {
  try {
    const sources = getSources(answers);
    await createSources(basepath, sources);
    console.log(chalk.greenBright("✓ 项目骨架创建成功"));
  } catch (error) {
    console.error(chalk.redBright("创建项目骨架失败:"), error.message);
    throw error;
  }
}

/**
 * 根据配置创建项目文件和目录
 * @param {string} basepath - 项目根目录路径
 * @param {Array} finalSources - 需要创建的文件和目录配置
 * @param {boolean} isTip - 是否显示创建提示信息
 * @throws {Error} 当创建过程中出现错误时抛出异常
 */
async function createSources(basepath, finalSources, isTip = true) {
  for (const source of finalSources) {
    try {
      const { type, path: p, src } = source;
      if (type === "file") {
        const parentDir = parse(p).dir;
        const srcPath = resolve(import.meta.dirname, "..", src);
        const destPath = resolve(basepath, p);

        if (relative(basepath, parentDir) !== "") {
          await createDir(resolve(basepath, parentDir));
        }
        await copyFile(srcPath, destPath);
        if (isTip) {
          console.log(chalk.dim(`✓ 创建文件 ${p}`));
        }
      } else if (type === "dir") {
        const destPath = resolve(basepath, p);
        await createDir(destPath);

        if (isTip) {
          console.log(chalk.dim(`✓ 创建文件夹 ${p}`));
        }
      } else {
        throw new Error(`未知的资源类型: ${type}`);
      }
    } catch (error) {
      console.error(chalk.red(`创建 ${source.path} 失败:`), error.message);
      throw error;
    }
  }
}

function getSources(answers) {
  // 检查 answers 对象及其属性是否存在
  if (!answers || !answers.languageType || !answers.languageType.value) {
    console.error("用户配置无效，请检查输入参数！");
    process.exit(1);
  }

  let finalSources;

  // 根据语言类型选择初始源码数组
  if (answers.languageType.value === "TypeScript") {
    finalSources = sources.concat(tsSources);
  } else {
    finalSources = sources.concat(jsSources);
  }

  finalSources = finalSources.concat(
    answers.languageType.value === "TypeScript"
      ? tsTsconfigStrictSources
      : jsTsconfigStrictSources
  );

  // 根据是否npm包选择额外的源码数组
  if (answers.npmPackage.value === "神岛地图项目") {
    finalSources = finalSources.concat(
      answers.languageType.value === "TypeScript"
        ? ts_dao3config
        : js_dao3config
    );
  } else {
    if (answers.isServer.value === "服务端") {
      finalSources = finalSources.concat(
        answers.languageType.value === "TypeScript"
          ? ts_dao3config_npmPackage_server
          : js_dao3config_npmPackage_server
      );
    } else {
      finalSources = finalSources.concat(
        answers.languageType.value === "TypeScript"
          ? ts_dao3config_npmPackage_client
          : js_dao3config_npmPackage_client
      );
    }
  }

  // 根据是否i18n选择额外的源码数组
  if (answers.i18n.value === "配置") {
    finalSources = finalSources.concat(i18nSources);
    finalSources = finalSources.concat(
      answers.languageType.value === "TypeScript"
        ? ts_i18nSources
        : js_i18nSources
    );
  }

  return finalSources;
}

export default {
  skeleton,
};

export { createSources };
